﻿/*
 * Copyright(C) 2012, ajayumi 保留所有权利。( All rights reserved. )
 * 
 * 文件名称：OracleAjMemberShipProvider.cs
 * 摘    要：
 * 当前版本：1.0
 * 作    者：黄乙冬 (ajayumi)
 * 联系方式：aj-ayumi@163.com; gajayumi@gmail.com; ajayumi@me.com;
 * 创建日期：2012年6月29日星期五
 */

using System.Web.Security;
using System;
using System.Configuration.Provider;
using ajayumi.Platform.Core.Security;
namespace ajayumi.Platform.Web.Security
{
    /// <summary>
    /// OracleAjMemberShipProvider 对 MembershipProvider 的 Oracle 实现
    /// </summary>
    public sealed class OracleAjMemberShipProvider : PetShop.Membership.OracleMembershipProvider
    {
        #region Variables

        #endregion

        #region Properties

        public CryptoProvider CryptoProvider
        {
            get;
            private set;
        }

        #endregion

        #region Constructors

        #endregion

        #region Internal Methods

        /// <summary>
        /// Encrypts, Hashes, or leaves the password clear based on the PasswordFormat.
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        protected override string EncodePassword(string password)
        {
            string encodedPassword = password;

            switch (PasswordFormat)
            {
                case MembershipPasswordFormat.Clear:
                    break;
                case MembershipPasswordFormat.Encrypted:
                    encodedPassword = this.CryptoProvider.Encrypt(password);
                    break;
                case MembershipPasswordFormat.Hashed:
                    encodedPassword = this.CryptoProvider.GetMD5Hash(password);
                    break;
                default:
                    throw new ProviderException("Unsupported password format.");
            }

            return encodedPassword;
        }

        /// <summary>
        /// Decrypts or leaves the password clear based on the PasswordFormat.
        /// </summary>
        /// <param name="encodedPassword"></param>
        /// <returns></returns>
        private string UnEncodePassword(string encodedPassword)
        {
            string password = encodedPassword;

            switch (PasswordFormat)
            {
                case MembershipPasswordFormat.Clear:
                    break;
                case MembershipPasswordFormat.Encrypted:
                    password = this.CryptoProvider.Decrypt(encodedPassword);
                    break;
                case MembershipPasswordFormat.Hashed:
                    throw new ProviderException("Cannot unencode a hashed password.");
                default:
                    throw new ProviderException("Unsupported password format.");
            }

            return password;
        }

        /// <summary>
        /// Converts a hexadecimal string to a byte array. Used to convert encryption
        /// key values from the configuration.
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        private byte[] HexToByte(string hexString)
        {
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

        /// <summary>
        /// Compares password values based on the MembershipPasswordFormat.
        /// </summary>
        /// <param name="password"></param>
        /// <param name="dbpassword"></param>
        /// <returns></returns>
        private bool CheckPassword(string password, string dbpassword)
        {
            string pass1 = password;
            string pass2 = dbpassword;

            switch (PasswordFormat)
            {
                case MembershipPasswordFormat.Encrypted:
                    pass2 = UnEncodePassword(dbpassword);
                    break;
                case MembershipPasswordFormat.Hashed:
                    pass1 = EncodePassword(password);
                    break;
                default:
                    break;
            }

            if (pass1 == pass2)
            {
                return true;
            }

            return false;
        }

        #endregion

        #region Override Methods

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            base.Initialize(name, config);

            #region Encrypted

            if (PasswordFormat == MembershipPasswordFormat.Encrypted)
            {
                this.CryptoProvider = ProviderFactory.CreateCryptoProvider();
            }

            #endregion
        }


        #endregion

    }
}
